﻿#region Copyright information
// 
// Copyright © 2005-2013 Yongkee Cho. All rights reserved.
// 
// This code is a part of the Biological Object Library and governed under the terms of the
// GNU Lesser General  Public License (LGPL) version 2.1 which accompanies this distribution.
// For more information on the LGPL, please visit http://bol.codeplex.com/license.
// 
// - Filename: DecisionTreeClassifierBase.cs
// - Author: Yongkee Cho
// - Email: yongkeecho@gmail.com
// - Date Created: 2012-12-08 8:26 AM
// - Last Modified: 2013-01-25 3:59 PM
// 
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using BOL.Linq.Probability;

namespace BOL.Algorithms.Classification
{
    public abstract class DecisionTreeClassifierBase<TFeature, TClass> : ClassifierBase<TFeature, TClass>
    {
        #region Public properties

        public IDecisionTreeNode<TClass> RootNode { get; private set; }

        #endregion

        #region Constructor

        protected DecisionTreeClassifierBase(IDecisionTreeNode<TClass> rootNode)
        {
            RootNode = rootNode;
        }

        #endregion

        #region Public method

        public override TClass Classify(TFeature[] features)
        {
            return Classify(RootNode, features, new Random());
        }

        private TClass Classify(IDecisionTreeNode<TClass> node, IList<TFeature> features, Random r)
        {
            return node.GetType() == typeof(ProbabilityTreeNode<TClass>) ?
                    ((ProbabilityTreeNode<TClass>)node).ProbabilityTable.Sample(r) :
                    Classify(node.Children.First(x => x.Key == ((ConditionTreeNode<TClass>)node).Condition(features[((ConditionTreeNode<TClass>)node).FeatureIndex]))
                , features
                , r);
        }

        #endregion

        #region Object overriden

        public override string ToString()
        {
            var prefix = String.Empty;
            RootNode.ToString(ref prefix, 0);
            return prefix;
        }

        #endregion
    }
}
